package cn.tanghom.app.oa.controller;

import cn.tanghom.content.model.ArticleCategory;
import cn.tanghom.content.service.ArticleCategoryService;
import cn.tanghom.app.oa.model.Candidate;
import cn.tanghom.app.oa.model.Position;
import cn.tanghom.app.oa.model.Talent;
import cn.tanghom.app.oa.repository.CandidateRepository;
import cn.tanghom.app.oa.repository.EduExpRepository;
import cn.tanghom.app.oa.repository.PositionRepository;
import cn.tanghom.app.oa.repository.TalentRepository;
import cn.tanghom.app.oa.repository.WorkExpRepository;
import cn.tanghom.app.oa.service.RecruitmentProcessService;
import cn.tanghom.app.oa.service.ResumeService;
import cn.tanghom.app.oa.service.impl.ResumeServiceWarper;
import cn.tanghom.app.system.model.User;
import cn.tanghom.app.system.service.OrganizationService;
import cn.tanghom.support.db.DynamicDataSourceHolder;
import cn.tanghom.support.page.Pager;
import cn.tanghom.support.tree.TreeObject;
import cn.tanghom.support.utils.CommonUtils;
import cn.tanghom.support.web.ContextHolder;

import org.flowable.common.engine.api.FlowableException;
import org.flowable.engine.*;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.TextCriteria;
import org.springframework.data.mongodb.core.query.TextQuery;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;


import javax.annotation.Resource;

import java.util.*;

import lombok.val;
import static cn.tanghom.support.web.BaseController.THEME_PATH;

/**
 * 职位招聘流程， 发布一个职位，然后触发招聘流程
 *
 * @author tanghom
 */
@Controller
@RequestMapping("/oa/position")
public class RecruitmentController {	
	
	private ResumeServiceWarper resumeService = new ResumeServiceWarper();	
	
	@Autowired
	private MongoOperations destination;
	
	@Resource
    private ArticleCategoryService articleCategoryService;	
	
	@Autowired
	private PositionRepository positionRepository;	
  
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;
    @Resource
    private ProcessEngine processEngine;
    @Resource
    private IdentityService identityService;    
    @Resource
    private RecruitmentProcessService matchService;   
    @Resource
    private CandidateRepository candidateRepository;
    
    @Resource
    private OrganizationService organizationService;
    
    
    /**
     * 当前职位下的人才推荐列表
     * @param id
     * @param model
     * @return
     */
    @RequestMapping(value = "/match-list/{id}", method = RequestMethod.GET)
    public String showMatchList(@PathVariable Long id,Model model) {
    	Position position = matchService.findById(id);
    	if(position==null) { return "error/404"; }
    	final Subject subject = SecurityUtils.getSubject();
    	String username = (String) subject.getPrincipal();       
       
        model.addAttribute("position", position);
        
        return THEME_PATH+"/oa/position/match-list";
    }
    
    @ResponseBody
    @RequestMapping(value = "/match-list/{id}", method = RequestMethod.POST)
    public List<Talent> getMatchList(@PathVariable Long id,String title) {
    	List<Talent> listDto;
    	PageRequest pager = new PageRequest(0,10);
        
        Position position = matchService.findById(id);
        Talent resume = new Talent(null,null);
        
        if(title==null){
        	title = position.getTitle();
        }        
        resume.jobTitle = title;        
        
        ExampleMatcher matcher = ExampleMatcher.matching()
        		.withIgnorePaths("annual_salary","annualSalary","createTime","updateTime","status")
                .withMatcher("categoryId", ExampleMatcher.GenericPropertyMatchers.startsWith()) //模糊查询匹配开头，即{username}%
                .withMatcher("jobTitle2" ,ExampleMatcher.GenericPropertyMatchers.contains());
          
        Example<Talent> example = Example.of(resume,matcher);
       
    	//Page<Resume> page = talentRepository.findAll( pager);
        //listDto = page.getContent();
        List<Candidate> page;
        //Long id = Long.parseLong((String)model.asMap().get("id"));
        
    	page = candidateRepository.findByPositionId(id);   
    	listDto = new ArrayList<>(page.size());
    	for(Candidate c: page){
    		Talent r = resumeService.getResume(null, c.getTalentId());
    		if(r!=null)
    			listDto.add(r);
    	}       
        return listDto;
    }
    
    
    //发布职位申请
    @RequestMapping(value = "/add",method =RequestMethod.GET)
    public ModelAndView createForm() {
        ModelAndView mav = new ModelAndView(THEME_PATH + "/oa/position/add");
        List<TreeObject> orgTree = organizationService.findToSelectTree();
        mav.addObject("organizations", orgTree);
        mav.addObject("position", new Position());
        return mav;
    }
    
    //修改职位申请
    @RequestMapping(value = "/edit/{id}",method =RequestMethod.GET)
    public ModelAndView modifyForm(@PathVariable Long id) {
    	Position position = matchService.findById(id);
        ModelAndView mav = new ModelAndView(THEME_PATH + "/oa/position/edit");
        List<TreeObject> orgTree = organizationService.findToSelectTree();
        mav.addObject("organizations", orgTree);
        mav.addObject("position", position);
        return mav;
    }

    //保存职位
    @RequestMapping(value = "/save", method =RequestMethod.POST)
    @ResponseBody
    public String save(Position position) {
        try {
            User loger = ContextHolder.getUser();
            position.setUserId(loger.getId());
            position.setCreateTime(new Date());       
           
            matchService.update(position);
            return CommonUtils.msgCallback(true, "职位已经保存", "", position.getTitle());            
        
        } catch (Exception e) {
            return CommonUtils.msgCallback(false, "系统内部错误,请联系管理员，" + e.getMessage(), "", null);
        }
    }
    
    /**
     * 职位列表
     *
     * @param categoryId 部门id
     * @param status 状态
     * @param model
     * @return
     */
    @RequestMapping(value = "/list", method = {RequestMethod.POST, RequestMethod.GET})
    public String list(String title, Long categoryId, Integer status, Long pageNo, Model model) {
        status = status == null || status < 0 ? null : status;
        categoryId = categoryId == null || categoryId < 0 ? null : categoryId;
        int pageIndex = pageNo!=null? pageNo.intValue():0;
        PageRequest pager = new PageRequest(pageIndex,20,Direction.DESC,"id");      
      
        Position criteria = new Position();  	
        
        ExampleMatcher matcher = ExampleMatcher.matching()
        		.withIgnorePaths("min_show_annual_salary","max_show_annual_salary","work_exp_required","status","annualSalary",
        				"degree_required","gender_required","work_exp_required","cityId","countryId","headCount","companyId")
                .withMatcher("titleId", ExampleMatcher.GenericPropertyMatchers.startsWith()) //模糊查询匹配开头，即{username}%
                .withMatcher("title" ,ExampleMatcher.GenericPropertyMatchers.contains());
          
      	if(categoryId!=null){
      		criteria.setDepId(categoryId);
        }
      	if(status!=null){
      		criteria.setStatus(status);          	
        }      	
        
    	if(title!=null && title.length()>0){
    		criteria.setTitle(title);
    	}
    	    	
    	Example<Position> example = Example.of(criteria,matcher);
    	Page<Position> page2 = positionRepository.findAll(example,pager);

    	Pager<Position> page = new Pager<Position>(page2.getContent());    
        page.setIndex(pageNo);
        page.setTotal(page2.getTotalElements());
        page.setRowCount(page2.getSize());
    	
        model.addAttribute("page", page);
        model.addAttribute("pageIndex",pageIndex);
        List<TreeObject> orgTree = organizationService.findToSelectTree();      
        model.addAttribute("organizations", orgTree);
        
        val pdf = repositoryService.createProcessDefinitionQuery().processDefinitionKey("recruitmentProcess").latestVersion().singleResult();
        model.addAttribute("processDefinitionId", pdf.getId());
        
        return THEME_PATH + "/oa/position/list";
    }
    
    //启动职位招聘流程:RecruitmentProcess
    @RequestMapping(value = "/start/{id}")
    @ResponseBody
    public String start(@PathVariable Long id) {
        try {
            User loger = ContextHolder.getUser();
            Position position = matchService.findById(id);
            position.setUserId(loger.getId());
            position.setUpdateTime(new Date());
            Map<String, Object> variables = new HashMap<String, Object>();
            ProcessInstance processInstance = matchService.startWorkflow(position, variables);
            return CommonUtils.msgCallback(true, "流程已启动", "", processInstance.getId());
        } catch (FlowableException e) {
            if (e.getMessage().indexOf("no processes deployed with key") != -1) {
                return CommonUtils.msgCallback(false, "系统内部错误，请联系管理员（没有部署流程，请在[工作流]->[流程管理]页面点击<重新部署流程>），" + e.getMessage(), "", null);
            } else {
                return CommonUtils.msgCallback(false, "系统内部错误,请联系管理员（启动请假流程失败），" + e.getMessage(), "", null);
            }
        } catch (Exception e) {
            return CommonUtils.msgCallback(false, "系统内部错误,请联系管理员，" + e.getMessage(), "", null);
        }
    }

    //给指定职位发送新收到的任意简历，然后让招聘流程匹配，继续运行
    @RequestMapping(value = "/receiveResume")
    @ResponseBody
    public String receiveResume(Long positionId,Long talentId) {
        try {
            User loger = ContextHolder.getUser();
            Position position = matchService.findById(positionId);
			String pi = position.getProcessInstanceId();
			Execution execution = runtimeService.createExecutionQuery()
			  .processInstanceId(pi)
			  .activityId("receive-resume")
			  .singleResult();
			
			if(execution==null){
				return CommonUtils.msgCallback(false, "错误，此职位的招聘流程没有启动，职位ID：" + positionId, "", null);
			}
			runtimeService.setVariable(execution.getId(), "talentId", talentId);
			runtimeService.trigger(execution.getId());
            return CommonUtils.msgCallback(true, "流程已启动", "", pi);
            
        } catch (FlowableException e) {
            if (e.getMessage().indexOf("no processes deployed with key") != -1) {
                return CommonUtils.msgCallback(false, "系统内部错误，请联系管理员（没有部署流程，请在[工作流]->[流程管理]页面点击<重新部署流程>），" + e.getMessage(), "", null);
            } else {
                return CommonUtils.msgCallback(false, "系统内部错误,请联系管理员（启动请假流程失败），" + e.getMessage(), "", null);
            }
        } catch (Exception e) {
            return CommonUtils.msgCallback(false, "系统内部错误,请联系管理员，" + e.getMessage(), "", null);
        }
    }



    /**
     * 我发布的职位招聘申请列表
     *
     */
    @RequestMapping(value = "/my_apply")
    public ModelAndView myTaskList(Long pageNo) {
        ModelAndView mav = new ModelAndView(THEME_PATH + "/oa/position/list");
        // 根据当前人的ID查询      
         
        User loger = ContextHolder.getUser();     
        
        val page2 = matchService.findPageByUserId(loger.getId(),1, pageNo); 
        //val page2 = matchService.findPageByUserId(7L,1, pageNo); 
        Pager<Position> page = new Pager<Position>(page2.getContent());    
        page.setIndex(pageNo);
        page.setTotal(page2.getTotalElements());
        page.setRowCount(page2.getSize());
        
        val pdf = repositoryService.createProcessDefinitionQuery().processDefinitionKey("recruitmentProcess").latestVersion().singleResult();
        mav.addObject("processDefinitionId", pdf.getId());
        mav.addObject("page", page);
        
        List<TreeObject> orgTree = organizationService.findToSelectTree();      
        mav.addObject("organizations", orgTree);
        return mav;
    }
    

    /**
     * 职位申请任务列表
     *
     */
    @RequestMapping(value = "/task/list")
    public ModelAndView taskList(Long pageNo) {
        ModelAndView mav = new ModelAndView(THEME_PATH + "/oa/position/task-list");
        // 根据当前人的ID查询
        List<Position> leaves = new ArrayList<Position>();
        Pager<Position> page = new Pager<Position>();
        page.setIndex(pageNo);
        User loger = ContextHolder.getUser();
        TaskQuery taskQuery = taskService.createTaskQuery().processDefinitionKey("recruitmentProcess").taskCandidateOrAssigned(loger.getLoginName());
        List<Task> tasks = taskQuery.listPage(page.startRow().intValue(),page.getSize());
        for (Task task : tasks) {
            String processInstanceId = task.getProcessInstanceId();
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
            if(processInstance == null){
            	continue;
            }
            String businessKey = processInstance.getBusinessKey();
            if (businessKey == null) {
                continue;
            }
            Position position = matchService.findById(Long.parseLong(businessKey));
            if (position == null) {
                continue;
            }
            mav.addObject("processInstance", processInstance);
            position.setTask(task);
            position.setProcessInstanceId(processInstanceId);
            leaves.add(position);
        }
        page.setTotalRecord(taskQuery.count());
        page.setItems(leaves);
        mav.addObject("page", page);
        mav.addObject("processKey","recruitmentProcess");       
        return mav;
    }

       

    /**
     * 读取详细数据
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "detail/{id}")
    @ResponseBody
    public Position getPosition(@PathVariable("id") Long id) {
        Position position = matchService.findById(id);
        return position;
    }

    /**
     * 读取详细数据
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "detail-with-vars/{id}/{taskId}")
    @ResponseBody
    public Map<String, Object> getPositionWithVars(@PathVariable("id") Long id, @PathVariable("taskId") String taskId) {
        Position position = matchService.findById(id);
        Map<String, Object> variables = taskService.getVariables(taskId);       
        variables.put("entity",position);
        return variables;
    }
    
    /**
     * 通过办理面试任务
     *
     * @param taskId
     * @return
     */
    @RequestMapping(value = "/task/complete/{id}", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String complete(@PathVariable("id") String taskId) {
        try {
            //Map<String, Object> variables = new HashMap<String, Object>();
            Map<String, Object> variables = taskService.getVariables(taskId);       
            variables.put("deptLeaderPass",true);
            variables.put("hrPass",true);
            taskService.complete(taskId,variables);
            return CommonUtils.msgCallback(true, "办理任务任务成功", "", null);
        } catch (Exception e) {
            return CommonUtils.msgCallback(false, "系统内部错误,请联系管理员，" + e.getMessage(), "", null);
        }
    }

}
